namespace ConsoleApp1;

public class CopyArrayUtil
{
    public static unsafe void Copy(byte[] source, int sourceOffset, byte[] target, int targetOffset, int count)
    {
        source = source ?? throw new System.ArgumentException("source or target is null");
        target = target ?? throw new System.ArgumentException("source or target is null");

        if ((sourceOffset < 0) || (targetOffset < 0) || (count < 0))
        {
            throw new System.ArgumentException("offset or bytes to copy is negative");
        }

        if ((source.Length - sourceOffset < count) ||
            (target.Length - targetOffset < count))
        {
            throw new System.ArgumentException("offset to end of array is less than bytes to be copied");
        }

        //question：为什么这里声明的不是 byte[]* 而是 byte* ?
        //answer：
        //在C#中，fixed语句用于固定一个数组的内存位置，以防止垃圾回收器移动它。在fixed语句中，使用byte*而不是byte[]*是因为我们要获取数组的指针，而不是数组本身的指针。
        // byte* 是指向一个字节的指针，它可以直接操作数组中的每个字节。
        // byte[]* 是指向一个字节数组的指针，这种情况很少用到，因为数组本身在内存中是连续的，直接使用指针操作更为方便和高效。
        // 通过使用fixed (byte* pSource = source, pTarget = target)，我们可以获取数组的起始地址（首元素的指针），从而在不受垃圾回收器影响的情况下直接操作内存。
        //为什么byte* pSource = source是数组第一个元素的指针
        // 固定内存位置：
        // fixed语句将数组固定在内存中，防止GC移动它。
        // 获取首元素指针：
        // 在fixed语句中，byte* pSource = source意味着pSource是source数组第一个元素的指针。fixed语句会自动处理指针的初始化，使得pSource指向source数组的第一个字节。
        // 指针偏移：
        // 通过指针偏移（如pSource[i + sourceOffset]），可以访问数组中的任意元素。
        fixed (byte* pSource = source, pTarget = target)
        {
            for (int i = 0; i < count; i++)
            {
                //question：为什么这里不是  *pTarget[i + targetOffset] = *pSource[i + sourceOffset] ？
                //answer：
                //数组索引语法：pSource[i + sourceOffset] 表示指针 pSource 加上偏移量 i + sourceOffset 之后的位置，并返回该位置的元素。这是最常见的写法，简洁明了。
                //指针算术语法：pSource + (i + sourceOffset) 表示指针 pSource 加上偏移量 i + sourceOffset 后的内存地址。在C语言等其他语言中，常常会看到这种写法。
                pTarget[i + targetOffset] = pSource[i + sourceOffset];
            }
        }
    }
}